package com.syh.jn.scm.infrastructure.repository.impl.operation.system;

import cn.redscarf.commons.util.other.ExtStringUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AggregateRepoMybatisImplTmpl;
import com.syh.jn.scm.domain.operation.repository.system.TerminalAccountOfPhoneReadRepository;
import com.syh.jn.scm.dto.operation.system.TerminaAccountOfPhone.TerminalAccountOfPhoneVo;
import com.syh.jn.scm.dto.operation.system.TerminaAccountOfPhone.TerminalAccountVo;
import com.syh.jn.scm.infrastructure.repository.model.system.AccountModel;
import com.syh.jn.scm.infrastructure.repository.model.system.AccountOfPhoneModel;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import lombok.extern.java.Log;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;

/**
 * Created by soci.song on 2018/12/13.
 */
@Log
@Repository("terminalAccountOfPhoneReadRepositoryImpl")
public class TerminalAccountOfPhoneReadRepositoryImpl implements TerminalAccountOfPhoneReadRepository {

  private AggregateRepoMybatisImplTmpl<TerminalAccountOfPhoneVo, AccountOfPhoneModel, Long> terminalAccountOfPhoneMybatisImpl = new AggregateRepoMybatisImplTmpl.Builder()
          .listTypeClass(TerminalAccountOfPhoneVo.class).modelClass(AccountOfPhoneModel.class).build();

  private AggregateRepoMybatisImplTmpl<TerminalAccountVo, AccountModel, Long> terminalAccountMybatisImpl = new AggregateRepoMybatisImplTmpl.Builder()
          .listTypeClass(TerminalAccountVo.class).modelClass(AccountModel.class).build();

  @Override
  public TerminalAccountOfPhoneVo getOne(Wrapper wrapper) {
    TerminalAccountOfPhoneVo vo = terminalAccountOfPhoneMybatisImpl.getOne(wrapper);
    if (vo == null) return null;
    Wrapper accountWe = Wrapper.build().append(Restrictions.eq("loginPhoneId", vo.getId()));
    List<TerminalAccountVo> accountVos = terminalAccountMybatisImpl.getList(accountWe);
    vo.setAccounts(accountVos);
    return vo;
  }

  @Override
  public List<TerminalAccountOfPhoneVo> getList(Wrapper wrapper) {
    return this.findListPage(wrapper, null, null);
  }

  @Override
  public boolean contains(Long aLong) {
    return terminalAccountOfPhoneMybatisImpl.contains(aLong);
  }

  @Override
  public List<TerminalAccountVo> getAccountVoList(Wrapper wrapper) {
    return this.terminalAccountMybatisImpl.getList(wrapper);
  }

  @Override
  public List<TerminalAccountVo> findAccountListPage(Wrapper wrapper, int startRow, int pageCount) {
    return this.terminalAccountMybatisImpl.findListPage(wrapper, startRow, pageCount);
  }

  @Override
  public int getAccountCount(Wrapper wrapper) {
    return this.terminalAccountMybatisImpl.getCount(wrapper);
  }

  @Override
  public List<TerminalAccountOfPhoneVo> findListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return terminalAccountOfPhoneMybatisImpl.findListPage(wrapper, startRow, count);
  }

  @Override
  public int getCount(Wrapper wrapper) {
    return terminalAccountOfPhoneMybatisImpl.getCount(wrapper);
  }

  @Override
  public TerminalAccountOfPhoneVo getById(Long aLong) {
    return terminalAccountOfPhoneMybatisImpl.getById(aLong);
  }

  public TerminalAccountOfPhoneReadRepositoryImpl() {
    // 查询account
    String accountOfPhoneTable = this.terminalAccountMybatisImpl.getModelTableName(AccountOfPhoneModel.class);
    String accountTable = this.terminalAccountMybatisImpl.getModelTableName(AccountModel.class);
    SQL accountSql = new SQL() {{
      SELECT(
              SQLAliasGenerateUtil.aliasGenerate(AccountModel.class, "account", null),
              "business_entity.business_name AS businessEntityName",
              "accountOfPhone.LOGIN_PHONE AS loginPhone"
      );
      FROM(
              ExtStringUtils.buildString(accountTable, " account")
      );
      LEFT_OUTER_JOIN(
              ExtStringUtils.buildString(accountOfPhoneTable, " accountOfPhone on accountOfPhone.ID = account.LOGIN_PHONE_ID")
      );
      LEFT_OUTER_JOIN(
              "(SELECT " +
                      " CONCAT(IFNULL(supplier.NAME,''),IFNULL(upstream.NAME,''),IFNULL(downstream.NAME,'')) AS 'business_name'," +
                      "account.ID AS 'accountId' " +
                      " FROM " +
                      " T_SYSTEM_ACCOUNT account " +
                      " LEFT JOIN t_base_supplier supplier on account.BUSINESS_ENTITY_ID = supplier.ID and account.TERMINAL_TYPE = 'SUPPLIER' " +
                      " LEFT JOIN t_base_upstream upstream on account.BUSINESS_ENTITY_ID = upstream.ID and account.TERMINAL_TYPE = 'UPSTREAM' " +
                      " LEFT JOIN t_base_downstream downstream on account.BUSINESS_ENTITY_ID = downstream.ID and account.TERMINAL_TYPE = 'DOWNSTREAM' " +
                      " GROUP BY account.ID )business_entity on business_entity.accountId = account.ID"
      );
    }};
    this.terminalAccountMybatisImpl.setQuerySql(accountSql);
    //初始化查询条件解析 account
    final HashMap<String, String> accountMap = new HashMap<>();
    accountMap.put("id", "accountOfPhone.ID");
    accountMap.put("loginPhone", "accountOfPhone.LOGIN_PHONE");
    accountMap.put("name", "accountOfPhone.NAME");
    accountMap.put("status", "accountOfPhone.STATUS");
    accountMap.put("terminalType", "accountOfPhone.TERMINAL_TYPE");
    accountMap.put("accountTerminalType", "account.TERMINAL_TYPE");
    accountMap.put("loginAccount", "account.LOGIN_ACCOUNT");
    accountMap.put("bindingStatus", "account.LOGIN_PHONE_ID");
    accountMap.put("businessEntityName", "business_entity.business_name");
    this.terminalAccountMybatisImpl.setWrapperParseMethods((propertyName) -> {
      return accountMap.get(propertyName);
    });


  }
}
